﻿using System.Linq;
using CTS.Com.Domain.Constants;
using CTS.Com.Domain.Exceptions;
using CTS.Com.Domain.Helper;
using CTS.Com.Domain.Utils;
using CTS.W._150101.Models.Domain.Dao.Admin;
using CTS.W._150101.Models.Domain.Model.Admin.Master.Items.Entry;
using CTS.W._150101.Models.Domain.Object.Admin.Items;

namespace CTS.W._150101.Models.Domain.Logic.Admin.Master.Items.Entry
{
    /// <summary>
    /// SaveLogic
    /// </summary>
    public class SaveLogic
    {
        #region Execute Method
        /// <summary>
        /// Xử lý save.
        /// </summary>
        /// <param name="inputObject">DataModel</param>
        /// <returns>DataModel</returns>
        public SaveDataModel Execute(SaveDataModel inputObject)
        {
            // Kiểm tra thông tin
            Check(inputObject);
            // Lưu thông tin
            var resultObject = SaveInfo(inputObject);
            // Kết quả trả về
            return resultObject;
        }
        #endregion

        #region Private Method
        /// <summary>
        /// Kiểm tra thông tin.
        /// </summary>
        /// <param name="inputObject">DataModel</param>
        private void Check(SaveDataModel inputObject)
        {
            // Khởi tạo biến cục bộ
            var processDao = new MasterItemsEntryDao();
            // Trường hợp là update all
            if (inputObject.IsUpdateAll) {
                // Lấy danh sách dữ liệu
                var listData = inputObject.ListDataLocale;
                // Khởi tạo biến dùng trong loop
                var i = 1;
                // Duyệt danh sách dữ liệu
                foreach (var data in listData) {
                    // Kiểm tra bắt buộc
                    if (DataCheckHelper.IsNull(data.ItemCd)) {
                        var msg = MessageHelper.GetMessage("E_MSG_00001", "Mã sản phẩm");
                        throw new ExecuteException("E_MSG_00010", "Danh sách", i, msg.MessageDetail);
                    }
                    if (DataCheckHelper.IsNull(data.ItemName)
                        || DataCheckHelper.IsNull(data.ItemSearchName)) {
                        var msg = MessageHelper.GetMessage("E_MSG_00001", "Tên sản phẩm");
                        throw new ExecuteException("E_MSG_00010", "Danh sách", i, msg.MessageDetail);
                    }
                    if (DataCheckHelper.IsNull(data.TypeCd)) {
                        var msg = MessageHelper.GetMessage("E_MSG_00001", "Loại sản phẩm");
                        throw new ExecuteException("E_MSG_00010", "Danh sách", i, msg.MessageDetail);
                    }
                    // Kiểm tra dữ liệu tồn tại
                    var isExist = processDao.IsExist(Logics.LOCALE_DEFAULT, data.ItemCd);
                    if (!isExist) {
                        var msg = MessageHelper.GetMessage("E_MSG_00016", "Sản phẩm");
                        throw new ExecuteException("E_MSG_00010", "Danh sách", i, msg.MessageDetail);
                    }
                    // Kiểm tra giá trị duy nhất
                    var isUnique = processDao.IsUnique(data.ItemCd, data.ItemSearchName);
                    var comparer = new KeyEqualityComparer<ItemObject>((k1, k2) =>
                            k1.ItemCd != k2.ItemCd
                            && k1.ItemSearchName == k2.ItemSearchName
                    );
                    // Kiểm tra giá trị duy nhất
                    if (!isUnique || listData.Contains(data, comparer)) {
                        var msg = MessageHelper.GetMessage("E_MSG_00017", "Tên sản phẩm");
                        throw new ExecuteException("E_MSG_00010", "Danh sách", i, msg.MessageDetail);
                    }
                    // Tăng giá trị i
                    i++;
                }
            } else {
                // Lấy đối tượng dữ liệu
                var dataBase = inputObject.DataLocaleBase;
                // Kiểm tra bắt buộc
                if (DataCheckHelper.IsNull(dataBase.ItemCd)) {
                    throw new ExecuteException("E_MSG_00001", "Mã sản phẩm");
                }
                if (DataCheckHelper.IsNull(dataBase.ItemName)
                    || DataCheckHelper.IsNull(dataBase.ItemSearchName)) {
                    throw new ExecuteException("E_MSG_00001", "Tên sản phẩm");
                }
                if (DataCheckHelper.IsNull(dataBase.TypeCd)) {
                    throw new ExecuteException("E_MSG_00001", "Loại sản phẩm");
                }
                // Kiểm tra dữ liệu tồn tại
                var isExist = processDao.IsExist(Logics.LOCALE_DEFAULT, dataBase.ItemCd);
                // Trường hợp là add
                if (inputObject.IsAdd && isExist) {
                    throw new DataExistException("Sản phẩm");
                }
                // Trường hợp là edit
                if (inputObject.IsEdit && !isExist) {
                    throw new DataNotExistException("Sản phẩm");
                }
                // Kiểm tra giá trị duy nhất
                if (!processDao.IsUnique(dataBase.ItemCd, dataBase.ItemSearchName)) {
                    throw new DataExistException("Tên sản phẩm");
                }
            }
        }

        /// <summary>
        /// Lưu thông tin.
        /// </summary>
        /// <param name="inputObject">DataModel</param>
        /// <returns>DataModel</returns>
        private SaveDataModel SaveInfo(SaveDataModel inputObject)
        {
            // Khởi tạo biến cục bộ
            var saveResult = new SaveDataModel();
            var processDao = new MasterItemsEntryDao();
            // Map dữ liệu
            DataHelper.CopyObject(inputObject, saveResult);
            // Trường hợp là update all
            if (inputObject.IsUpdateAll) {
                // Lấy danh sách dữ liệu
                var listData = inputObject.ListDataLocale;
                // Duyệt danh sách dữ liệu
                foreach (var data in listData) {
                    // Lưu đối tượng dữ liệu
                    processDao.Update(data);
                }
            } else {
                // Lấy đối tượng dữ liệu
                var dataLocaleBase = inputObject.DataLocaleBase;
                // Lưu đối tượng dữ liệu
                if (inputObject.IsAdd) {
                    processDao.Insert(dataLocaleBase);
                } else {
                    processDao.Update(dataLocaleBase);
                }
            }
            // Submit thông tin
            processDao.SubmitChanges();
            // Kết quả trả về
            return saveResult;
        }
        #endregion
    }
}